package org.goldenport.g3.adapters

import java.io._
import java.net.URL
import org.goldenport.g3._
import org.goldenport.g3.messages._
import org.goldenport.g3.messages.filestore._
import com.asamioffice.goldenport.io.{ UFile, UURL, UIO }

/**
 * @since   Apr. 13, 2010
 * @version Sep. 18, 2010
 * @author  ASAMI, Tomoharu
 */
class FileStoreAdapter(val uri: String) extends G3Adapter {
  val url = UURL.getURLFromFileOrURLName(uri);
  val file = UURL.getActiveFile(url)

  override protected def do_Action(content: AnyRef, parcel: G3Parcel, ctx: G3AgentContext): AnyRef = {
    content match {
      case create: Create => {
        create_file(create.path, create.openInputStream())
      }
      case read: Read => {
        read_file(read.path)
      }
      case write: Write => {
        write_file(write.path, write.openInputStream())
      }
      case remove: Remove => {
        remove_file(remove.path)
      }
      case get: Get => {
        read_file(get.uri)
      }
      case post: Post => {
        create_file(post.uri, post.content)
      }
      case put: Put => {
        write_file(put.uri, put.content)
      }
      case delete: Delete => {
        remove_file(delete.uri)
      }
      case _ => {
        error("???:" + content)
      }
    }
  }

  private def create_file(path: String, content: AnyRef): AnyRef = {
    content match {
      case blob: Blob => create_file(path, blob.openInputStream())
    }
  }

  private def create_file(path: String, optionIn: Option[InputStream]): AnyRef = {
    optionIn match {
      case Some(in) => write_file(path, in)
      case None => UFile.createFile(new File(file, path), "")
    }
    None
  }

  private def read_file(path: String): AnyRef = {
    val f = new File(file, path)
    val in = new FileInputStream(f)
    try {
      UIO.stream2Bytes(in)
    } finally {
      in.close()
    }
  }

  private def write_file(path: String, content: AnyRef): AnyRef = {
    content match {
      case blob: Blob => write_file(path, blob.openInputStream())
    }
  }

  private def write_file(path: String, in: InputStream): AnyRef = {
    UFile.createFile(new File(file, path), in)
    None
  }

  private def remove_file(path: String): AnyRef = {
    val f = new File(file, path)
    f.delete()
    None
  }
}
